﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using netEntity = tuReserva.Model;
using wsSchema = tuReserva.Service.USAL.tuReserva;

namespace tuReserva.Service
{
	public class ApplicationService
	{
		private wsSchema.ApplicationService _proxy;
		private netEntity.User _currUser;

		public ApplicationService()
		{
			this._proxy = new wsSchema.ApplicationService();
		}

		public netEntity.User getCurrentUser()
		{
			return this._currUser;
		}

		public bool Login(netEntity.User u)
		{
			wsSchema.LoginRequest request = new wsSchema.LoginRequest();

			request.User = this.getWsSchema(u);

			wsSchema.LoginResponse response = this._proxy.Login(request);

			if (response.MessageList.Length == 0)
			{
				this._currUser = this.getNetEntity(response.User);
			}

			return (response.MessageList.Length == 0);
		}

		public List<netEntity.Restaurant> getRestaurantList(netEntity.User user)
		{
			wsSchema.GetRestaurantListRequest request = new wsSchema.GetRestaurantListRequest();

			request.UserID = user.ID.ToString();

			wsSchema.GetRestaurantListResponse response = this._proxy.GetRestaurantList(request);

			List<netEntity.Restaurant> list = new List<netEntity.Restaurant>();

			foreach (wsSchema.Restaurant r in response.RestaurantList)
			{
				list.Add(this.getNetEntity(r));
			}

			return list;
		}

		public List<netEntity.Restaurant> getRestaurantList()
		{
			wsSchema.GetRestaurantListRequest request = new wsSchema.GetRestaurantListRequest();

			request.UserID = String.Empty;

			wsSchema.GetRestaurantListResponse response = this._proxy.GetRestaurantList(request);

			List<netEntity.Restaurant> list = new List<netEntity.Restaurant>();

			foreach (wsSchema.Restaurant r in response.RestaurantList)
			{
				list.Add(this.getNetEntity(r));
			}

			return list;
		}

		public void insertRestaurant(netEntity.Restaurant restaurant)
		{
			wsSchema.InsertRestaurantRequest request = new wsSchema.InsertRestaurantRequest();

			request.Restaurant = this.getWsSchema(restaurant);

			wsSchema.InsertRestaurantResponse response = this._proxy.InsertRestaurant(request);
		}

		public List<netEntity.Category> getCategoryList()
		{
			wsSchema.GetCategoryListRequest request = new wsSchema.GetCategoryListRequest();

			wsSchema.GetCategoryListResponse response = this._proxy.GetCategoryList(request);

			List<netEntity.Category> list = new List<netEntity.Category>();

			foreach (wsSchema.Category c in response.CategoryList)
			{
				list.Add(this.getNetEntity(c));
			}

			return list;
		}

		public List<netEntity.Reserve> getReserveList(netEntity.User user)
		{
			wsSchema.GetReserveListRequest request = new wsSchema.GetReserveListRequest();

			request.UserID = user.ID.ToString();

			wsSchema.GetReserveListResponse response = this._proxy.GetReserveList(request);

			List<netEntity.Reserve> list = new List<netEntity.Reserve>();

			foreach (wsSchema.Reserve r in response.ReserveList)
			{
				list.Add(this.getNetEntity(r));
			}

			return list;
		}

		public List<netEntity.Table> getTableList(string restaurantID)
		{
			wsSchema.GetTableListRequest request = new wsSchema.GetTableListRequest();

			request.RestaurantID = restaurantID;

			wsSchema.GetTableListResponse response = this._proxy.GetTableList(request);

			List<netEntity.Table> list = new List<netEntity.Table>();

			foreach (wsSchema.Table t in response.TableList)
			{
				list.Add(this.getNetEntity(t));
			}

			return list;
		}

		public bool insertReserve(netEntity.Reserve reserve)
		{
			wsSchema.InsertReserveRequest request = new wsSchema.InsertReserveRequest();

			request.Reserve = this.getWsSchema(reserve);

			wsSchema.InsertReserveResponse response = this._proxy.InsertReserve(request);

			return Boolean.Parse(response.isOK);
		}

		public void updateUser(netEntity.User user)
		{
			wsSchema.UpdateUserRequest request = new wsSchema.UpdateUserRequest();

			request.User = this.getWsSchema(user);

			wsSchema.UpdateUserResponse response = this._proxy.UpdateUser(request);
		}

		public void insertUser(netEntity.User user)
		{
			wsSchema.InsertUserRequest request = new wsSchema.InsertUserRequest();

			request.User = this.getWsSchema(user);

			wsSchema.InsertUserResponse response = this._proxy.InsertUser(request);
		}

		public void rateRestaurant(netEntity.Reserve reserve, string points)
		{
			wsSchema.RateRestaurantRequest request = new wsSchema.RateRestaurantRequest();

			request.Reserve = new wsSchema.Reserve();
			request.Reserve.ID = reserve.ID.ToString();
			
			request.Reserve.Restaurant = new wsSchema.Restaurant();
			request.Reserve.Restaurant.ID = reserve.Restaurant.ID.ToString();

			request.Points = points;

			wsSchema.RateRestaurantResponse response = this._proxy.RateRestaurant(request);
		}

		public bool validateReserve(netEntity.Reserve reserve)
		{
			wsSchema.ValidateReserveRequest request = new wsSchema.ValidateReserveRequest();

			request.Reserve = this.getWsSchema(reserve);

			wsSchema.ValidateReserveResponse response = this._proxy.ValidateReserve(request);

			return Boolean.Parse(response.isOK);
		}

		public bool cancelReserve(string reserveID)
		{
			wsSchema.DeleteReserveRequest request = new wsSchema.DeleteReserveRequest();

			request.ReserveID = reserveID;

			wsSchema.DeleteReserveResponse response = this._proxy.DeleteReserve(request);

			return Boolean.Parse(response.isOK);
		}

		public List<netEntity.Reserve> getLoadedReserveList(netEntity.User user)
		{
			wsSchema.GetLoadedReserveListRequest request = new wsSchema.GetLoadedReserveListRequest();

			request.UserID = user.ID.ToString();

			wsSchema.GetLoadedReserveListResponse response = this._proxy.GetLoadedReserveList(request);

			List<netEntity.Reserve> list = new List<netEntity.Reserve>();

			foreach (wsSchema.Reserve r in response.ReserveList)
			{
				list.Add(this.getNetEntity(r));
			}

			return list;
		}

		public bool updateReserve(netEntity.Reserve reserve)
		{
			wsSchema.UpdateReserveRequest request = new wsSchema.UpdateReserveRequest();

			request.Reserve = new wsSchema.Reserve();

			request.Reserve.ID = reserve.ID.ToString();
			request.Reserve.State = reserve.State;

			wsSchema.UpdateReserveResponse response = this._proxy.UpdateReserve(request);

			return Boolean.Parse(response.isOK);
		}

#region getWsSchemas
		private wsSchema.User getWsSchema(netEntity.User user)
		{
			wsSchema.User u = new wsSchema.User();

			u.ID = user.ID.ToString();
			u.Address = user.Adress;
			u.Cellphone = user.Cellphone;
			u.Mail = user.Mail;
			u.Name = user.Name;
			u.Password = user.Password;
			u.Telephone = user.Telephone;
			u.Type = user.Type;
			u.UserName = user.UserName;

			return u;
		}

		private wsSchema.Restaurant getWsSchema(netEntity.Restaurant restaurant)
		{
			wsSchema.Restaurant r = new wsSchema.Restaurant();
			r.Category = new wsSchema.Category();
			r.User = new wsSchema.User();

			r.User = this.getWsSchema(restaurant.User);
			r.Name = restaurant.Name;
			r.Address = restaurant.Address;
			r.Telephone = restaurant.Telephone;
			r.Points = restaurant.Points.ToString();
			r.Category.ID = restaurant.Category.ID.ToString();
			r.OpenTime = restaurant.Open_time;
			r.CloseTime = restaurant.Close_time;
			r.OpenDays = restaurant.Open_days;
			r.Description = restaurant.Description;

			r.TableList = new wsSchema.Table[restaurant.TableList.Count];

			for (int i = 0; i < restaurant.TableList.Count; i++)
			{
				r.TableList[i] = this.getWsSchema(restaurant.TableList.ElementAt(i));
			}

			return r;
		}

		private wsSchema.Table getWsSchema(netEntity.Table table)
		{
			wsSchema.Table t = new wsSchema.Table();

			t.ID = table.ID.ToString();
			t.Description = table.Description;

			return t;
		}

		private wsSchema.Reserve getWsSchema(netEntity.Reserve reserve)
		{
			wsSchema.Reserve r = new wsSchema.Reserve();

			r.ID = reserve.ID.ToString();
			r.Date = reserve.Date;
			r.Time = reserve.Time;
			r.Restaurant = this.getWsSchema(reserve.Restaurant);

			return r;
		}
#endregion

#region getNetEntity
		private netEntity.User getNetEntity(wsSchema.User user)
		{
			netEntity.User u = new netEntity.User();

			u.ID = Int32.Parse(user.ID);
			u.Mail = user.Mail;
			u.Name = user.Name;
			u.Password = user.Password;
			u.Telephone = user.Telephone;
			u.Type = user.Type;
			u.UserName = user.UserName;
			u.Adress = user.Address;
			u.Cellphone = user.Cellphone;

			return u;
		}

		private netEntity.Restaurant getNetEntity(wsSchema.Restaurant restaurant)
		{
			netEntity.Restaurant r = new netEntity.Restaurant();

			r.ID = Int32.Parse(restaurant.ID);
			r.Name = restaurant.Name;
			r.Address = restaurant.Address;
			r.Category = (restaurant.Category != null) ? this.getNetEntity(restaurant.Category) : r.Category;
			r.Description = restaurant.Description;
			r.Points = (restaurant.Points != null) ? Decimal.Parse(restaurant.Points) : 0;
			r.Open_days = restaurant.OpenDays;
			r.Open_time = restaurant.OpenTime;
			r.Close_time = restaurant.CloseTime;
			r.Telephone = restaurant.Telephone;

			if (restaurant.TableList != null)
			{
				foreach (wsSchema.Table t in restaurant.TableList)
				{
					r.TableList.Add(this.getNetEntity(t));
				}
			}

			return r;
		}

		private netEntity.Category getNetEntity(wsSchema.Category category)
		{
			netEntity.Category c = new netEntity.Category();

			c.ID = Int32.Parse(category.ID);
			c.Description = category.Description;

			return c;
		}

		private netEntity.Table getNetEntity(wsSchema.Table table)
		{
			netEntity.Table t = new netEntity.Table();

			t.ID = Int32.Parse(table.ID);
			t.Description = table.Description;
			t.Status = table.Status;

			return t;
		}

		private netEntity.Reserve getNetEntity(wsSchema.Reserve reserve)
		{
			netEntity.Reserve r = new netEntity.Reserve();

			r.ID = Int32.Parse(reserve.ID);
			r.Date = reserve.Date;
			r.Time = reserve.Time;
			r.State = reserve.State;
			r.Restaurant = this.getNetEntity(reserve.Restaurant);

			if (reserve.User != null)
			{
				r.Costumer.Name = reserve.User.Name;
				r.Costumer.Mail = reserve.User.Mail;
				r.Costumer.Telephone = reserve.User.Telephone;
			}

			return r;
		}
#endregion
	}
}
